<template>
	<el-cascader
		v-model="internalValue"
		:options="options"
		:props="cascaderProps"
		clearable
		filterable
		@change="handleChange"
	/>
</template>

<script lang="ts" setup>
import { PropType, ref, watch } from 'vue';
import { CascaderProps, CascaderNode } from 'element-plus';

interface CascaderOption {
	value: string | number
	label: string
	children?: CascaderOption[]
	disabled?: boolean
}

const props = defineProps({
	modelValue: {
		type: Array as () => Array<string | number>,
		default: () => []
	},
	options: {
		type: Array as PropType<CascaderNode[]>,
		required: true
	},
	placeholder: {
		type: String,
		default: '请选择'
	}
})

const emit = defineEmits(['update:modelValue', 'change'])

const internalValue = ref<(string | number)[]>([])

// 处理 props 变化
watch(() => props.modelValue, (newVal) => {
	internalValue.value = newVal ? [...newVal] : []
}, { immediate: true })



// 构建父节点到子节点列表的映射
const buildParentChildrenMap = (options: CascaderOption[]): Map<string | number, Set<string | number>> => {
	const map = new Map<string | number, Set<string | number>>()

	const traverse = (nodes: CascaderOption[], parentValue?: string | number) => {
		nodes.forEach(node => {
			if (parentValue !== undefined) {
				if (!map.has(parentValue)) {
					map.set(parentValue, new Set())
				}
				map.get(parentValue)?.add(node.value)
			}

			if (node.children) {
				traverse(node.children, node.value)
			}
		})
	}

	traverse(options)
	return map
}

// 处理选择变化
const handleChange = (values: any) => {
	const parentChildrenMap = buildParentChildrenMap(props.options)
	const leafNodes = findAllLeafNodes(props.options)

	const result = new Set<string | number>()
	const parentSelectedMap = new Map<string | number, string | number>() // 记录每个父节点下已选的子节点

	// 先处理非叶子节点
	values.forEach(value => {
		if (!leafNodes.has(value)) {
			result.add(value)
		}
	})

	// 再处理叶子节点，确保同一父级下只保留最后一个选择的子节点
	values.forEach(value => {
		if (leafNodes.has(value)) {
			// 找到这个叶子节点的父节点
			let parent: string | number | undefined
			parentChildrenMap.forEach((children, parentValue) => {
				if (children.has(value)) {
					parent = parentValue
				}
			})

			if (parent) {
				// 如果这个父节点已经有选中的子节点，则替换
				if (parentSelectedMap.has(parent)) {
					result.delete(parentSelectedMap.get(parent)!)
				}
				result.add(value)
				parentSelectedMap.set(parent, value)
			} else {
				// 没有父节点的叶子节点直接添加
				result.add(value)
			}
		}
	})

	const finalValues = Array.from(result)
	emit('update:modelValue', finalValues)
	emit('change', finalValues)
	internalValue.value = finalValues
}

// 查找所有叶子节点
const findAllLeafNodes = (options: CascaderOption[]): Set<string | number> => {
	const leafNodes = new Set<string | number>()

	const traverse = (nodes: CascaderOption[]) => {
		nodes.forEach(node => {
			if (!node.children || node.children.length === 0) {
				leafNodes.add(node.value)
			} else {
				traverse(node.children)
			}
		})
	}

	traverse(options)
	return leafNodes
}
</script>

